package perso.marcr.lst.api;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

import perso.marcr.lst.model.Scenario;
import perso.marcr.lst.model.Status;
import perso.marcr.util.ConverterByte;
import perso.marcr.util.Date;
import perso.marcr.util.Unit;

public class BufferFile {

	private int bufferSize = 1024*1024*2;

	private byte[] buffer;

	private double nbByteToCopy = 0;

	private String directory=null;

	private double fileByteSize=0;

	private double nbrTotalBytesCopied = 0;

	private double nbFileToCopy=0;

	private InfoThread infoThread = null;

	/**
	 * @param directory
	 * @param nbByteToCopy in Bytes
	 * @param fileByteSize in Bytes
	 */
	public BufferFile(String directory, double nbByteToCopy, double fileByteSize)
	{
		new File(directory).mkdirs();
		this.directory = directory;
		this.nbByteToCopy = nbByteToCopy;
		this.fileByteSize = fileByteSize; 

		// Init buffer:		
		bufferSize = (int) Math.min(fileByteSize, bufferSize);		
		buffer=new byte[bufferSize];
		Arrays.fill(buffer, (byte) 0);

		nbFileToCopy=nbByteToCopy/fileByteSize;
	}	

	public int getBufferSize() {
		return bufferSize;
	}

	public void setBufferSize(int bufferSize) {
		this.bufferSize = bufferSize;
	}	

	public double getNbrTotalBytesCopied() {
		return nbrTotalBytesCopied;
	}

	public void setNbrTotalBytesCopied(double nbrTotalBytesCopied) {
		this.nbrTotalBytesCopied = nbrTotalBytesCopied;
	}	

	public InfoThread getInfoThread() {
		return infoThread;
	}

	public void setInfoThread(InfoThread infoThread) {
		this.infoThread = infoThread;
	}

	public void makeTest(Scenario scenarioUpload, Scenario scenarioDownload, String szLabel, boolean bKeepTestFiles) throws IOException
	{
		makeTestUpload(scenarioUpload, szLabel);
		makeTestDownload(scenarioDownload, szLabel);

		// remove directory:
		if(!bKeepTestFiles)
		{
			new File(directory+"\\test-"+szLabel).delete();
		}
	}

	public void makeTestUpload(Scenario scenario, String szLabel) throws IOException
	{
		// Init variables:
		nbrTotalBytesCopied = 0;

		String labelFileInfo = String.format("UPLOAD - %s - %s = %s x %s files (Mo/s)", 
				szLabel,
				ConverterByte.toHumanReadable(nbByteToCopy, Unit.OCTET),
				ConverterByte.toHumanReadable(fileByteSize, Unit.OCTET),
				nbFileToCopy
				);

		scenario.setTitle(labelFileInfo);
		scenario.setStatus(Status.RUNNING);
		scenario.setDateStart(Date.getNow());

		infoThread = new InfoThread(this, scenario);
		infoThread.start();
		try
		{
			for(int i=1; i<=nbFileToCopy; i++)
			{			
				double nbrBytesToCopyForEachBuffer= fileByteSize/bufferSize;

				FileOutputStream fos = new FileOutputStream(directory+"\\test-"+szLabel);

				while(nbrBytesToCopyForEachBuffer > 0)
				{
					nbrBytesToCopyForEachBuffer--;
					nbrTotalBytesCopied+=bufferSize;
					fos.write(buffer,0,bufferSize); // write a Byte.
				}

				fos.close();
			}
			scenario.setStatus(Status.SUCCESS);
		}
		catch(IOException e)
		{
			scenario.setStatus(Status.ERROR);
		}


		infoThread.setBloop(false);
	}

	public void makeTestDownload(Scenario scenario, String szLabel) throws IOException
	{
		// Init variables:
		nbrTotalBytesCopied = 0;		

		String labelFileInfo = String.format("DOWNLOAD - %s - %s = %s x %s files (Mo/s)", 
				szLabel,
				ConverterByte.toHumanReadable(nbByteToCopy, Unit.OCTET),
				ConverterByte.toHumanReadable(fileByteSize, Unit.OCTET),
				nbFileToCopy
				);

		scenario.setTitle(labelFileInfo);
		scenario.setStatus(Status.RUNNING);
		scenario.setDateStart(Date.getNow());

		infoThread = new InfoThread(this, scenario);
		infoThread.start();
		try
		{
			for(int i=1; i<=nbFileToCopy; i++)
			{			
				double nbrBytesToCopyForEachBuffer= fileByteSize/bufferSize;

				FileInputStream fos = new FileInputStream(directory+"\\test-"+szLabel);

				while(nbrBytesToCopyForEachBuffer > 0)
				{
					nbrBytesToCopyForEachBuffer--;
					nbrTotalBytesCopied+=bufferSize;
					fos.read(buffer,0,bufferSize); // write a Byte.
				}

				fos.close();
			}
			scenario.setStatus(Status.SUCCESS);
		}
		catch(IOException e)
		{
			scenario.setStatus(Status.ERROR);
		}


		infoThread.setBloop(false);
	}

}
